package com.jplus.framework.bean;

import java.lang.annotation.Annotation;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.jplus.framework.AppConstant;
import com.jplus.framework.InstanceFactory;
import com.jplus.framework.bean.annotation.Component;
import com.jplus.framework.util.FormatUtil;
import com.jplus.framework.util.SecurityUtil;

/**
 * 初始化所有bean实例
 * 
 * @author Yuanqy
 *
 */
public class BeanHandle {
	private static final Logger logger = LoggerFactory.getLogger(BeanHandle.class);
	/**
	 * 所有组件类[未实例]
	 */
	public static Set<Class<?>> beanSet = new HashSet<Class<?>>();

	/**
	 * 环绕组件[init/destroy][未实例]
	 */
	public static final Set<Class<?>> beanAround = new HashSet<Class<?>>();

	/**
	 * Temp Bean Map [已实例]
	 */
	private static Map<String, Object> beanTempMap = new ConcurrentHashMap<String, Object>();

	/**
	 * BeanMap[已实例,最终的容器组件]
	 */
	private static final Map<String, Object> beanIocMap = new ConcurrentHashMap<String, Object>();

	static {
		String[] scanPkg = (AppConstant.CONFIG.AppScanPKG.getValue() + ";" + AppConstant.CONFIG.AppJwebPKG.getValue()).split(";");
		for (String pkg : scanPkg) {
			beanSet.addAll(InstanceFactory.getClassScanner().getListByAnnotation(pkg, Component.class, true));
		}
		logger.info("\tPackage[{}]：{}", beanSet.size(), scanPkg);
		addAround();
	}

	public static void setBean(Annotation anno, Class<?> cls, Object obj) {
		beanIocMap.put(SecurityUtil.MD5(anno.toString() + cls.toString()), obj);
	}

	@SuppressWarnings("unchecked")
	public static <T> T getBean(Annotation anno, Class<T> cls) {
		return (T) beanIocMap.get(SecurityUtil.MD5(anno.toString() + cls.toString()));
	}

	/**
	 * 设置 Bean 实例
	 */
	public static void setBean(Class<?> cls, Object obj) {
		beanIocMap.put(SecurityUtil.MD5(cls.toString()), obj);
	}

	/**
	 * 获取 Bean 实例
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getBean(Class<T> cls) {
		return (T) beanIocMap.get(SecurityUtil.MD5(cls.toString()));
	}

	/**
	 * 设置临时 Bean 实例
	 */
	public static void setTempBean(Class<?> cls, Object obj) {
		beanTempMap.put(SecurityUtil.MD5(cls.toString()), obj);
	}

	/**
	 * 获取临时 Bean 实例
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getTempBean(Class<T> cls) {
		return (T) beanTempMap.get(SecurityUtil.MD5(cls.toString()));
	}

	/**
	 * 清空 Bean 缓存
	 */
	public static void clearCache() {
		beanTempMap.clear();
		beanSet.clear();
	}

	private static void addAround() {
		// ==附加 环绕
		for (Class<?> cls : beanSet) {
			Component comp = cls.getAnnotation(Component.class);
			if (comp != null && (!FormatUtil.isEmpty(comp.initMethod()) || !FormatUtil.isEmpty(comp.destroyMethod()))) {
				BeanHandle.beanAround.add(cls);
			}
		}
	}

}
